/**
 * FileContentManager is a Java based file manager desktop application, it can
 * show, edit and manipulate the content of the files archived inside a zip.
 * 
 * Copyright (C) 2007
 * 
 * Created by Camila Sanchez [http://mimix.wordpress.com/], Rafael Naufal
 * [http://rnaufal.livejournal.com] and Rodrigo [rdomartins@gmail.com]
 * 
 * FileContentManager is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with FileContentManager; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package br.com.jteam.jfcm.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.LayoutManager;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.CompoundBorder;

import br.com.jteam.jfcm.controller.listener.CloseAboutDialogListener;
import br.com.jteam.jfcm.gui.bundle.BaseBundle;
import br.com.jteam.jfcm.gui.util.GUIUtil;

/**
 * Exibe um di&aacute;logo com informac&otilde;es sobre os desenvolvedores da aplica&ccedil;&atilde;o.
 * 
 * <p>
 * O di&aacute;logo apresenta &iacute;cones e descri&ccedil;&otilde;es de cada um dos autores do programa.
 * </p>
 * <p>
 * O di&aacute;logo pode ser fechado com a tecla "ESC".
 * </p>
 */
public class AboutDialog extends JDialog
{
	public AboutDialog()
	{
		super();
		setTitle(BaseBundle.getValue("dialog.about.caption"));
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		setModal(true);
		setPreferredSize(new Dimension(750, 550));
		add(createContentPanel());
		addKeyListener(new CloseAboutDialogListener(this));
		pack();
		centerWindow();
		setVisible(true);
	}

	private void centerWindow()
	{
		GUIUtil.centerWindow(this);
	}

	/**
	 * Cria um painel com a descric&atilde;o e i&iacute;cone representativo de um dos autores
	 * do programa.
	 * 
	 * @param nameLabel
	 *            A label com o nome do autor
	 * @param icon
	 *            O icone representando um autor
	 * @param descLabel
	 *            A label contendo o texto descritivo do autor
	 * @param constraints
	 *            A posicao do icone (leste ou oeste) em relacao a descricao do
	 *            autor.
	 * @return Um painel contendo o icone e a descricao de um autor
	 */
	private JPanel createAboutPanel(JPanel urlPanel,
									JLabel nameLabel,
									Icon icon,
									JLabel descLabel,
									String constraints)
	{
		CompoundBorder border =
						BorderFactory.createCompoundBorder(	BorderFactory.createLineBorder(Color.BLACK),
															BorderFactory.createEmptyBorder(10,
																							10,
																							10,
																							10));
		JPanel iconPane = createPanel(Color.WHITE, new BorderLayout());
		iconPane.add(new JLabel(icon));
		iconPane.add(nameLabel, BorderLayout.SOUTH);
		iconPane.setPreferredSize(new Dimension(110, 110));
		JPanel aboutPanel = createPanel(Color.WHITE, new BorderLayout());
		aboutPanel.add(iconPane, constraints);
		JPanel informationPanel = createPanel(Color.WHITE, new BorderLayout());
		informationPanel.add(descLabel, BorderLayout.NORTH);
		informationPanel.add(urlPanel, BorderLayout.WEST);
		informationPanel.setBorder(border);
		aboutPanel.add(informationPanel, BorderLayout.CENTER);
		return aboutPanel;
	}

	private JPanel makeEmailPanel(String developer)
	{
		JPanel emailPanel = createPanel(Color.WHITE, new FlowLayout());
		emailPanel.add(getDeveloperEmailLabel());
		emailPanel.add(getDeveloperEmail(developer));
		return emailPanel;
	}

	private JPanel makeBlogWithEmailPanel(String developer)
	{
		JPanel emailPanel = makeEmailPanel(developer);
		JPanel blogsPanel = createPanel(Color.WHITE, new BorderLayout());
		blogsPanel.add(getDeveloperBlogsLabel(), BorderLayout.WEST);
		blogsPanel.add(getDeveloperBlog(developer), BorderLayout.EAST);
		JPanel blogsAndEmailPanel =
						createPanel(Color.WHITE, new BorderLayout());
		blogsAndEmailPanel.add(emailPanel, BorderLayout.NORTH);
		blogsAndEmailPanel.add(blogsPanel, BorderLayout.CENTER);
		return blogsAndEmailPanel;
	}

	/**
	 * @return O pain&eacute;l com as informa&ccedil;&otilde;es e a imagem dos desenvolvedores da
	 *         aplica&ccedil;&atilde;o.
	 */
	public JPanel createContentPanel()
	{
		JPanel contentPanel = createPanel(Color.BLACK, new BorderLayout());
		Box box = Box.createVerticalBox();
		JPanel aboutPanel1 =
						createAboutPanel(	makeEmailPanel("developer1"),
											createDeveloperNameLabel(BaseBundle.getValue("developer1.name")),
											createIcon("/images/about/developer1_picture.jpg"),
											getDeveloperInformation("developer1"),
											BorderLayout.WEST);
		JPanel aboutPanel2 =
						createAboutPanel(	makeBlogWithEmailPanel("developer2"),
											createDeveloperNameLabel(BaseBundle.getValue("developer2.name")),
											createIcon("/images/about/developer2_picture.jpg"),
											getDeveloperInformation("developer2"),
											BorderLayout.EAST);
		JPanel aboutPanel3 =
						createAboutPanel(	makeEmailPanel("developer3"),
											createDeveloperNameLabel(BaseBundle.getValue("developer3.name")),
											createIcon("/images/about/developer3_picture.jpg"),
											getDeveloperInformation("developer3"),
											BorderLayout.WEST);
		box.add(aboutPanel1);
		box.add(aboutPanel2);
		box.add(aboutPanel3);
		contentPanel.add(box);
		return contentPanel;
	}

	/**
	 * 
	 * @param developerName
	 *            Nome do desenvolvedor.
	 * @return Um JLanel contendo o nome do desenvolvedor.
	 */
	private JLabel createDeveloperNameLabel(String developerName)
	{
		JLabel nameLabel = new JLabel(developerName);
		nameLabel.setHorizontalAlignment(SwingConstants.CENTER);
		nameLabel.setFont(new Font("Serif", Font.ITALIC + Font.BOLD, 12));
		nameLabel.setForeground(Color.BLUE);
		return nameLabel;
	}

	/**
	 * @param imagePath
	 *            Caminho da imagem.
	 * @return Um ImageIcon representando a imagem.
	 */
	private ImageIcon createIcon(String imagePath)
	{
		return new ImageIcon(getClass().getResource(imagePath));
	}

	/**
	 * @param info
	 *            Informa&ccedil;&otilde;es a serem exibidas na &aacute;rea de conte�do do di&aacute;logo.
	 * @return Um JLabel com as informa&ccedil;&otilde;es sobre os desenvolvedores.
	 */
	private JLabel createInformationLabel(String info)
	{
		String htmlText = "<html>" + info + "</html>";
		return new JLabel(htmlText);
	}

	/**
	 * @param borderColor
	 *            Cor da borda do painel.
	 * @return Um JPanel com a uma borda da cor informada.
	 */
	private JPanel createPanel(Color borderColor, LayoutManager layout)
	{
		JPanel jpanel = new JPanel();
		jpanel.setLayout(layout);
		jpanel.setBorder(BorderFactory.createLineBorder(borderColor));
		jpanel.setBackground(Color.WHITE);
		return jpanel;
	}

	/**
	 * 
	 * @param developerKePart&iacute;cula
	 *            da chave de bundle que acessa as informa&ccedil;&otilde;es de um
	 *            desenvolvedor.
	 * @return Um JLabel com as informa&ccedil;&otilde;es do desenvolvedor.
	 */
	private JLabel getDeveloperInformation(String developerKey)
	{
		String info =
						BaseBundle.getValue(developerKey
										+ ".html.style.description");
		return createInformationLabel(info);
	}

	private JLabel getDeveloperEmail(String developerKey)
	{
		String info = BaseBundle.getValue(developerKey + ".html.style.email");
		JLabel emailLabel = new JLabel(info);
		emailLabel.setForeground(Color.BLUE);
		addOpenURLAction(emailLabel, true);
		return emailLabel;
	}

	private JLabel getDeveloperBlog(String developerKey)
	{
		String info = BaseBundle.getValue(developerKey + ".html.style.blog");
		JLabel blogLabel = new JLabel(info);
		blogLabel.setForeground(Color.BLUE);
		addOpenURLAction(blogLabel, false);
		return blogLabel;
	}

	private JLabel getDeveloperEmailLabel()
	{
		String info = BaseBundle.getValue("developer.html.style.email");
		return createInformationLabel(info);
	}

	private JLabel getDeveloperBlogsLabel()
	{
		String info = BaseBundle.getValue("developer.html.style.blog");
		return createInformationLabel(info);
	}

	private void addOpenURLAction(final JLabel label, boolean isEmail)
	{
		addOpenURLAction(label, label.getText(), isEmail);
	}

	private void addOpenURLAction(	final JLabel l,
									final String url,
									final boolean isEmail)
	{
		l.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseEntered(MouseEvent e)
			{
				l.setCursor(new Cursor(Cursor.HAND_CURSOR));
			}

			@Override
			public void mouseExited(MouseEvent e)
			{
				l.setCursor(Cursor.getDefaultCursor());
			}

			@Override
			public void mouseClicked(MouseEvent event)
			{
				URI uri;
				try
				{
					if (isEmail)
					{
						uri = new URI("mailto:" + url);
						Desktop.getDesktop().mail(uri);
					} else
					{
						uri = new URI(url);
						Desktop.getDesktop().browse(uri);
					}
				} catch (URISyntaxException e)
				{
					throw new RuntimeException(e);
				} catch (IOException e)
				{
					throw new RuntimeException(e);
				}
			}
		});
	}
}
